local fs = require "nixio.fs"

local m

if luci.sys.call("pidof redsocks2 >/dev/null") == 0 then
	m = Map("redsocks2", translate("RedSocks2"), translate("RedSocks2 is running"))
else
	m = Map("redsocks2", translate("RedSocks2"), translate("RedSocks2 is not running"))
end

ss_method = {
	"table",
	"rc4",
	"rc4-md5",
	"aes-128-cfb",
	"aes-192-cfb",
	"aes-256-cfb",
	"bf-cfb",
	"cast5-cfb",
	"des-cfb",
	"camellia-128-cfb",
	"camellia-192-cfb",
	"camellia-256-cfb",
	"cast5-cfb",
	"des-cfb",
	"idea-cfb",
	"rc2-cfb",
	"seed-cfb",
	"ARC4-128",
	"AES-128-CFB128",
	"AES-192-CFB128",
	"AES-256-CFB128",
	"BLOWFISH-CFB64",
	"CAMELLIA-128-CFB128",
	"CAMELLIA-192-CFB128",
	"CAMELLIA-256-CFB128",
}

redsocks2 = m:section(TypedSection, "redsocks2", translate("General Setting"))
redsocks2.anonymous = true

proxy = redsocks2:tab("proxy", "Proxy")

enabled = redsocks2:taboption("proxy", Flag, "enabled", translate("Enable"))
enabled.default ='0'
enabled.rmempty = false

local_port = redsocks2:taboption("proxy", Value, "local_port", translate("Local Port"))
local_port.datatype = "port"
local_port.default = "1080"
local_port.rmempty = false

auto_proxy = redsocks2:taboption("proxy", ListValue, "auto_proxy", translate("Auto Proxy"))
auto_proxy:value("0", translate("Disable"))
auto_proxy:value("1", translate("Enable"))
auto_proxy.default = '1'
auto_proxy.rmempty = false

timeout = redsocks2:taboption("proxy", Value, "timeout", translate("Timeout"))
timeout.datatype = "uinteger"
timeout.default = "5"
timeout.rmempty = false

proxy_type = redsocks2:taboption("proxy", ListValue, "proxy_type", translate("Proxy Type"))
proxy_type:value("socks5", translate("SOCKS5"))
proxy_type:value("vpn", translate("VPN"))
proxy_type:value("shadowsocks", translate("ShadowSocks"))
proxy_type:value("goagent", translate("GoAgent"))
proxy_type.default = 'socks5'
proxy_type.rmempty = false

-- Socks5
socks5_ip = redsocks2:taboption("proxy", Value, "socks5_ip", translate("Proxy IP"))
socks5_ip.datatype = "ipaddr"
socks5_ip.default = "127.0.0.1"
socks5_ip:depends("proxy_type", "socks5")

socks5_port = redsocks2:taboption("proxy", Value, "socks5_port", translate("Proxy Port"))
socks5_port.datatype = "port"
socks5_port.default = "1080"
socks5_port:depends("proxy_type", "socks5")

socks5_username = redsocks2:taboption("proxy", Value, "socks5_username", translate("Username"), translate("(Optional)"))
socks5_username:depends("proxy_type", "socks5")

socks5_password = redsocks2:taboption("proxy", Value, "socks5_password", translate("Password"), translate("(Optional)"))
socks5_password.password = true
socks5_password:depends("proxy_type", "socks5")

-- VPN
vpn_interface = redsocks2:taboption("proxy", Value, "vpn_interface", translate("VPN Interface"))
vpn_interface:value("tun0")
vpn_interface.default = "tun0"
vpn_interface:depends("proxy_type", "vpn")

-- ShadowSocks
shadowsocks_ip = redsocks2:taboption("proxy", Value, "shadowsocks_ip", translate("Server Host"))
shadowsocks_ip.datatype = "ipaddr"
shadowsocks_ip.default = '127.0.0.1'
shadowsocks_ip:depends("proxy_type", "shadowsocks")

shadowsocks_port = redsocks2:taboption("proxy", Value, "shadowsocks_port", translate("Server Port"))
shadowsocks_port.datatype = "port"
shadowsocks_port.default = "1080"
shadowsocks_port:depends("proxy_type", "shadowsocks")

shadowsocks_encrypt_method = redsocks2:taboption("proxy", ListValue, "shadowsocks_encrypt_method", translate("Encrypt Method"))
for i,v in ipairs(ss_method) do
	shadowsocks_encrypt_method:value(v)
end
shadowsocks_encrypt_method.default = "table"
shadowsocks_encrypt_method:depends("proxy_type", "shadowsocks")

shadowsocks_password = redsocks2:taboption("proxy", Value, "shadowsocks_password", translate("Password"))
shadowsocks_password.password = true
shadowsocks_password.default = "password"
shadowsocks_password:depends("proxy_type", "shadowsocks")

-- GoAgent
goagent_ip = redsocks2:taboption("proxy", Value, "goagent_ip", translate("GoAgent IP"))
goagent_ip.datatype = "ipaddr"
goagent_ip.default = "192.168.1.1"
goagent_ip:depends("proxy_type", "goagent")

goagent_port = redsocks2:taboption("proxy", Value, "goagent_port", translate("GoAgent Port"))
goagent_port.datatype = "port"
goagent_port.default = "8080"
goagent_port:depends("proxy_type", "goagent")

--Ignore
ignore = redsocks2:tab("ignore", translate("Ignore IP"))
ignore_china = redsocks2:taboption("ignore", Flag, "ignore_china", translate("China IP List"), "/etc/ipset/china")
ignore_china.default = "0"
ignore_china.rmempty = false
ignore_user = redsocks2:taboption("ignore", TextValue, "ignore_user", "User Ignore IP")
ignore_user.template = "cbi/tvalue"
ignore_user.size = 30
ignore_user.rows = 5
ignore_user.wrap = "off"
function ignore_user.cfgvalue(self, section)
	return fs.readfile("/etc/ipset/ignore") or ""
end
function ignore_user.write(self, section, value)
	if value then
		value = value:gsub("\r\n?", "\n")
		fs.writefile("/tmp/ignore", value)
		fs.mkdirr("/etc/ipset")
		if (fs.access("/etc/ipset/ignore") ~= true or luci.sys.call("cmp -s /tmp/ignore /etc/ipset/ignore") == 1) then
			fs.writefile("/etc/ipset/ignore", value)
		end
		fs.remove("/tmp/ignore")
	end
end

-- LAN Access Control
lan_control = redsocks2:tab("lan_control", translate("LAN Control"))

lan_control_mode = redsocks2:taboption("lan_control", ListValue, "lan_control_mode", translate("LAN Control"))
lan_control_mode:value("0", translate("Disabled"))
lan_control_mode:value("1", translate("Allow listed only"))
lan_control_mode:value("2", translate("Allow all except listed"))
lan_control_mode.default = "0"
lan_control_mode.rmempty = false

lan_ip = redsocks2:taboption("lan_control", DynamicList, "lan_ip", translate("LAN IP"))
lan_ip.datatype = "ipaddr"

-- UDP Redirect
udp = redsocks2:tab("udp", translate("UDP Redirect"))

udp_enabled = redsocks2:taboption("udp", Flag, "udp", translate("Enable"))
udp_enabled.default = "0"
udp_enabled.rmempty = false

udp_proxy_type = redsocks2:taboption("udp", ListValue, "udp_proxy_type", translate("Proxy Type"))
udp_proxy_type:value("socks5", translate("SOCKS5"))
udp_proxy_type:value("vpn", translate("VPN"))
udp_proxy_type:value("shadowsocks", translate("ShadowSocks"))
udp_proxy_type.default = 'socks5'
udp_proxy_type.rmempty = false

socks5_ip = redsocks2:taboption("udp", Value, "udp_socks5_ip", translate("Proxy IP"))
socks5_ip.datatype = "ipaddr"
socks5_ip.default = "127.0.0.1"
socks5_ip:depends("udp_proxy_type", "socks5")

socks5_port = redsocks2:taboption("udp", Value, "udp_socks5_port", translate("Proxy Port"))
socks5_port.datatype = "port"
socks5_port.default = "1080"
socks5_port:depends("udp_proxy_type", "socks5")

socks5_username = redsocks2:taboption("udp", Value, "udp_socks5_username", translate("Username"), translate("(Optional)"))
socks5_username:depends("udp_proxy_type", "socks5")

socks5_password = redsocks2:taboption("udp", Value, "udp_socks5_password", translate("Password"), translate("(Optional)"))
socks5_password.password = true
socks5_password:depends("udp_proxy_type", "socks5")

vpn_interface = redsocks2:taboption("udp", Value, "udp_vpn_interface", translate("VPN Interface"))
vpn_interface:value("tun0")
vpn_interface.default = "tun0"
vpn_interface:depends("udp_proxy_type", "vpn")

shadowsocks_ip = redsocks2:taboption("udp", Value, "udp_shadowsocks_ip", translate("Server Host"))
shadowsocks_ip.datatype = "ipaddr"
shadowsocks_ip.default = '127.0.0.1'
shadowsocks_ip:depends("udp_proxy_type", "shadowsocks")

shadowsocks_port = redsocks2:taboption("udp", Value, "udp_shadowsocks_port", translate("Server Port"))
shadowsocks_port.datatype = "port"
shadowsocks_port.default = "1080"
shadowsocks_port:depends("udp_proxy_type", "shadowsocks")

shadowsocks_encrypt_method = redsocks2:taboption("udp", ListValue, "udp_shadowsocks_encrypt_method", translate("Encrypt Method"))
for i,v in ipairs(ss_method) do
	shadowsocks_encrypt_method:value(v)
end
shadowsocks_encrypt_method.default = "table"
shadowsocks_encrypt_method:depends("udp_proxy_type", "shadowsocks")

shadowsocks_password = redsocks2:taboption("udp", Value, "udp_shadowsocks_password", translate("Password"))
shadowsocks_password.password = true
shadowsocks_password.default = "password"
shadowsocks_password:depends("udp_proxy_type", "shadowsocks")

udp_timeout = redsocks2:taboption("udp", Value, "udp_timeout", translate("Timeout"))
udp_timeout.datatype = "uinteger"
udp_timeout.default = "3"

udp_dest = redsocks2:taboption("udp", DynamicList, "udp_dest", translate("Destination"), translate("Dest IP:Port#LocalPort ( eg. 8.8.8.8:53#1053 )"))


-- TCP DNS
tcp_dns = redsocks2:tab("tcp_dns", translate("TCP DNS"))

tcp_dns_enabled = redsocks2:taboption("tcp_dns", Flag, "tcp_dns", translate("Enable"))
tcp_dns_enabled.default = "0"
tcp_dns_enabled.rmempty = false

tcp_dns_local_port = redsocks2:taboption("tcp_dns", Value, "tcp_dns_local_port", translate("Local Port"))
tcp_dns_local_port.datatype = "port"
tcp_dns_local_port.default = "3053"
tcp_dns_local_port.rmempty = false

tcp_dns_timeout = redsocks2:taboption("tcp_dns", Value, "tcp_dns_timeout", translate("Timeout"))
tcp_dns_timeout.datatype = "uinteger"
tcp_dns_timeout.default = "3"
tcp_dns_timeout.rmempty = false

tcp_dns_server1 = redsocks2:taboption("tcp_dns", Value, "tcp_dns_server1", translate("DNS Server #1"))
tcp_dns_server1.datatype = "ipaddr"
tcp_dns_server1.default = "8.8.8.8"
tcp_dns_server1.rmempty = false

tcp_dns_server2 = redsocks2:taboption("tcp_dns", Value, "tcp_dns_server2", translate("DNS Server #2"), translate("DNS Server with TCP Support."))
tcp_dns_server2.datatype = "ipaddr"
tcp_dns_server2.default = "8.8.4.4"
tcp_dns_server2.rmempty = false


-- IPCache
ipcache = redsocks2:tab("ipcache", translate"IPCache")

ipcache_enabled = redsocks2:taboption("ipcache", Flag, "ipcache", translate("Enable"))
ipcache_enabled.default = "0"
ipcache_enabled.rmempty = false

ipcache_size = redsocks2:taboption("ipcache", Value, "ipcache_size", translate("Size (K)"))
ipcache_size.datatype = "integer"
ipcache_size.default = "4"
ipcache_size.rmempty = false

ipcache_file = redsocks2:taboption("ipcache", Value, "ipcache_file", translate("File"))
ipcache_file.default = "/tmp/ipcache.txt"
ipcache_size.rmempty = false

ipcache_stale_time = redsocks2:taboption("ipcache", Value, "ipcache_stale_time", translate("Stale Time"))
ipcache_stale_time.datatype = "integer"
ipcache_stale_time.default = "7200"
ipcache_stale_time.rmempty = false

ipcache_autosave_interval = redsocks2:taboption("ipcache", Value, "ipcache_autosave_interval", translate("Autosave Interval"), translate("seconds, \"0\" for Disable"))
ipcache_autosave_interval.datatype = "integer"
ipcache_autosave_interval.default = "3600"
ipcache_autosave_interval.rmempty = false

ipcache_port_check = redsocks2:taboption("ipcache", Flag, "ipcache_port_check", translate("Port Check"))
ipcache_port_check.default = "0"
ipcache_port_check.rmempty = false

ipcache_no_quick_check_seconds = redsocks2:taboption("ipcache", Value, "ipcache_no_quick_check_seconds", translate("Cache Time"), translate("\"0\" for all the time"))
ipcache_no_quick_check_seconds.datatype = "integer"
ipcache_no_quick_check_seconds.default = "300"
ipcache_no_quick_check_seconds.rmempty = false

ipcache_quick_connect_timeout = redsocks2:taboption("ipcache", Value, "ipcache_quick_connect_timeout", translate("Timeout"), translate("\"0\" for proxy direct"))
ipcache_quick_connect_timeout.datatype = "integer"
ipcache_quick_connect_timeout.default = "3"
ipcache_quick_connect_timeout.rmempty = false

-- Log
log = redsocks2:tab("log", translate"Log")

log = redsocks2:taboption("log", Flag, "log", translate("Enable"))
log.default = "0"
log.rmempty = false

log_debug = redsocks2:taboption("log", Flag, "log_debug", translate("Log Debug"))
log_debug.default = "0"
log_debug.rmempty = false

log_info = redsocks2:taboption("log", Flag, "log_info", translate("Log Info"))
log_info.default = "0"
log_info.rmempty = false

log_file = redsocks2:taboption("log", Value, "log_file", translate("Log File"))
log_file.default = "/dev/null"
log_file.rmempty = false


return m
